<template>
  <div class="max-w-4xl mx-auto p-6">
    <h1 class="text-2xl font-semibold">排序（Sort）</h1>
    <p class="mt-4 text-gray-600">对文本的行进行排序。支持大小写忽略、去重、去空行、按长度排序等选项。</p>

    <div class="mt-6 space-y-4">
      <div class="flex items-center space-x-3">
        <label class="text-sm text-gray-700">排序方式：</label>
        <select v-model="mode" class="border rounded px-2 py-1">
          <option value="alpha">字典顺序（默认）</option>
          <option value="length">按长度</option>
        </select>

        <label class="ml-4 flex items-center space-x-2 text-sm">
          <input type="checkbox" v-model="ignoreCase" class="form-checkbox" />
          <span>忽略大小写</span>
        </label>

        <label class="ml-4 flex items-center space-x-2 text-sm">
          <input type="checkbox" v-model="unique" class="form-checkbox" />
          <span>去重</span>
        </label>

        <label class="ml-4 flex items-center space-x-2 text-sm">
          <input type="checkbox" v-model="skipEmpty" class="form-checkbox" />
          <span>忽略空行</span>
        </label>

        <label class="ml-4 flex items-center space-x-2 text-sm">
          <input type="checkbox" v-model="reverse" class="form-checkbox" />
          <span>降序</span>
        </label>
      </div>

      <div class="flex space-x-4">
        <div class="flex-1">
          <div class="flex items-center justify-between mb-2">
            <label class="text-sm font-medium">输入</label>
            <div class="space-x-2">
              <button @click="pasteFromClipboard" class="text-sm text-blue-500">粘贴</button>
              <input ref="fileInput" type="file" accept=".txt" class="hidden" @change="onFileChange" />
              <button @click="() => $refs.fileInput.click()" class="text-sm text-blue-500">打开文件</button>
            </div>
          </div>
          <textarea v-model="inputText" rows="12" class="w-full border rounded p-2"></textarea>
        </div>

        <div class="flex-1">
          <div class="flex items-center justify-between mb-2">
            <label class="text-sm font-medium">输出</label>
            <div class="space-x-2">
              <button @click="copyOutput" class="text-sm text-blue-500">复制</button>
              <button @click="downloadOutput" class="text-sm text-blue-500">下载</button>
            </div>
          </div>
          <textarea :value="outputText" rows="12" readonly class="w-full border rounded p-2 bg-gray-50"></textarea>
        </div>
      </div>

      <div class="flex items-center space-x-3">
        <button @click="processNow" class="primary-button">立即排序</button>
        <button @click="clearAll" class="secondary-button">清空</button>
        <nuxt-link to="/text-tools" class="ml-auto text-sm text-blue-500">返回文本工具</nuxt-link>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, onMounted } from 'vue'
import { useTools } from '~/composables/useTools'

const { copyToClipboard, downloadFile, readFile, readImageFile, debounce } = useTools()

const inputText = ref('')
const outputText = ref('')

const mode = ref('alpha') // 'alpha' | 'length'
const ignoreCase = ref(true)
const unique = ref(false)
const skipEmpty = ref(true)
const reverse = ref(false)

const fileInput = ref(null)

const processNow = () => {
  const raw = inputText.value || ''
  const lines = raw.split(/\r?\n/)

  let processed = lines.map(l => l)

  // trim lines
  processed = processed.map(l => l.trim())

  if (skipEmpty.value) {
    processed = processed.filter(l => l.length > 0)
  }

  if (unique.value) {
    const seen = new Set()
    processed = processed.filter(l => {
      const key = ignoreCase.value ? l.toLowerCase() : l
      if (seen.has(key)) return false
      seen.add(key)
      return true
    })
  }

  if (mode.value === 'length') {
    processed.sort((a, b) => a.length - b.length)
  } else {
    processed.sort((a, b) => {
      if (ignoreCase.value) {
        return a.localeCompare(b, undefined, { sensitivity: 'accent' })
      }
      return a.localeCompare(b)
    })
  }

  if (reverse.value) processed.reverse()

  outputText.value = processed.join('\n')
}

const debouncedProcess = debounce(processNow, 300)

watch([inputText, mode, ignoreCase, unique, skipEmpty, reverse], () => {
  debouncedProcess()
})

const copyOutput = async () => {
  if (!outputText.value) return
  await copyToClipboard(outputText.value)
}

const downloadOutput = () => {
  if (!outputText.value) return
  downloadFile(outputText.value, 'sorted.txt')
}

const pasteFromClipboard = async () => {
  try {
    const text = await navigator.clipboard.readText()
    inputText.value = text
  } catch (e) {
    console.error('读取剪贴板失败', e)
  }
}

const onFileChange = async (e) => {
  const file = e.target.files && e.target.files[0]
  if (!file) return
  try {
    const content = await readFile(file)
    inputText.value = content
  } catch (err) {
    console.error('读取文件失败', err)
  } finally {
    // reset value so same file can be selected again
    e.target.value = ''
  }
}

const clearAll = () => {
  inputText.value = ''
  outputText.value = ''
}

onMounted(() => {
  // initial process if any
  processNow()
})
</script>
